home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’95 / CantTouchThis / CantTouchThis.c < prev    next >
C/C++ Source or Header  |  1995-06-24  |  9KB  |  424 lines

  1. /*
  2.     CantTouchThis        Show interesting effects
  3.  
  4.     @MacHack    bh         noEsis Software Construction
  5. */
  6.  
  7.  
  8. /*
  9.     Last Build:
  10.     
  11.                 22jun95
  12.     
  13.     DOCS:
  14.         
  15.  
  16. */
  17.  
  18.  
  19. //****************************************************************
  20. //                                                I N C L U D E S
  21.  
  22. #include <Types.h>
  23. #include <Memory.h>
  24. #include <SetUpA4.h>
  25. #include <Quickdraw.h>
  26. #include <QDOffscreen.h>
  27. #include <LowMem.h>
  28. #include <Errors.h>
  29. #include <GestaltEqu.h>
  30. #include <Resources.h>
  31. #include <Events.h>
  32. #include <Windows.h>
  33. #include <Sound.h>
  34. #include <AppleEvents.h>
  35. #include <AEObjects.h>
  36. #include <AERegistry.h>
  37. #include <AEPackObject.h>
  38. #include <Aliases.h>
  39. #include <Processes.h>
  40. #include <Sound.h>
  41.  
  42.  
  43. #include <SANE.h>
  44.  
  45. #ifndef TRUE
  46.     #define FALSE 0
  47.     #define TRUE (!FALSE)
  48. #endif
  49.  
  50. #define DEBUG
  51.  
  52. #ifdef DEBUG
  53. pascal void NumToString(long,StringPtr);
  54. #define ASSERT(x) { if (!(x)) { Str255 lineString; NumToString(__LINE__,lineString); DebugStr(lineString); }}
  55. #else
  56. #define ASSERT(x) ;
  57. #endif
  58.  
  59.  
  60. //****************************************************************
  61. //                                                C O N S T A N T S
  62.  
  63.  
  64. // ShowInit 
  65. #define kOkMac        128
  66. #define kNotOkMac    130
  67.  
  68.  
  69.  
  70. //****************************************************************
  71. //                                                G L O B A L S
  72.  
  73. struct NInitGlobals
  74. {
  75.     Handle        pH;
  76.  
  77. };
  78. typedef struct NInitGlobals NInitGlobals;
  79.  
  80. NInitGlobals                *gP;
  81. static void                 *gOldJGNE;
  82. Handle                        gSound;
  83. SndChannelPtr                gSndChP;
  84.  
  85. //****************************************************************
  86. //                                                F O R W A R D S
  87.  
  88.  
  89. OSErr DoInstallPatch(void);
  90. void DoAnimation( Rect trshR);
  91.  
  92. pascal void * SetJGNEFilter (void *newFilter);
  93. Boolean myGNE (EventRecord *event, Boolean preResult);
  94. void myJGNE (void);
  95.  
  96. extern OSErr
  97.  GetScriptableFinderTrashPos( Boolean usesystemmode, AESendMode sendmode, Boolean sendToSelf, Rect *r);
  98.  
  99. //****************************************************************
  100. void main( void )
  101. {
  102.     Handle    tH;
  103.     OSErr    err;
  104.     void *me; asm { MOVE.L A0,me }
  105.  
  106.  
  107.     //Debugger();
  108.     
  109.     RememberA0 ( );
  110.     SetUpA4();
  111.  
  112.     DetachResource (RecoverHandle (me));
  113.  
  114.     tH = GetResource( 'PICT', 200);    
  115.     if ( tH != 0) {
  116.         DetachResource( tH);
  117.     }
  118. /*
  119.     gSound = GetResource('snd ',128);
  120.     if (gSound) {
  121.         DetachResource(gSound);
  122.     }
  123.     err = SndNewChannel( &gSndChP, sampledSynth, initMono, 0);
  124.     if (err != noErr) {
  125.         gSndChP = NULL;
  126.     }
  127. */
  128. gSound = NULL;
  129. gSndChP = NULL;
  130.  
  131.     // ok, go to town
  132.     gOldJGNE = SetJGNEFilter (myJGNE);
  133.  
  134.     gP = (NInitGlobals*) NewPtrSysClear( sizeof(NInitGlobals));
  135.     if ( !gP ) {
  136.         err = memFullErr;
  137.         goto DONE;
  138.     }
  139.  
  140.     gP->pH = tH;    
  141.  
  142.  
  143.  
  144.     DONE:
  145. /*
  146.     if ( err ) {
  147.         ShowIconFamily( kNotOkMac);
  148.         if ( gP )
  149.             DisposPtr( (Ptr)gP );
  150.     } else {
  151.         ShowIconFamily( kOkMac);
  152.         // resource is already marked 'locked', so no HLock() here...
  153.     }
  154. */
  155.  
  156.     RestoreA4();
  157.  
  158.     return;
  159. }
  160.  
  161.  
  162. //****************************************************************
  163. #define JGNEFilter     0x29A
  164.  
  165. static pascal void * SetJGNEFilter (void *newFilter)
  166. {
  167.     void *result = *(void **) JGNEFilter;
  168.     *(long *) JGNEFilter = (long) newFilter;
  169.     return (result);
  170. }
  171.  
  172. //****************************************************************
  173. static Boolean myGNE (EventRecord *event, Boolean preResult)
  174. {
  175.     Rect    tR;
  176.     Boolean postResult = preResult;
  177.  
  178.     if (event->what == mouseDown) {
  179.         if ( *(long*)0x912 == 'inde' ) {
  180.             GetScriptableFinderTrashPos( TRUE, kAEWaitReply, TRUE, &tR);
  181.             if ( PtInRect( event->where, &tR) && *(long*)0x17E == 0) {
  182.                     DoAnimation( tR);
  183.                     event->what = nullEvent;
  184.             }
  185.         }
  186.     }
  187.  
  188.     return (postResult);
  189. }
  190.  
  191.  
  192. //****************************************************************
  193. static void myJGNE (void)
  194. {
  195.     static Boolean inJGNE;
  196.     
  197.     asm
  198.     {
  199.         MOVE.L        A1,A0            ; save event record pointer from __GetA4
  200.         JSR            __GetA4            ; point A1 at our A4
  201.         MOVE.L        A4,-(A7)        ; save old A4
  202.         MOVE.L        (A1),A4            ; get new A4
  203.         MOVE.L        A0,A1            ; restore old A1
  204.         TST.B        inJGNE            ; is myJGNE busy?
  205.         BNE            @1                ; yes, so bail
  206.         MOVE.B        #true,inJGNE    ; mark myJGNE busy
  207.         MOVE.W        D0,-(A7)        ; push pre-result
  208.         MOVE.L        A1,-(A7)        ; push event record pointer
  209.         JSR            myGNE            ; do the real work
  210.         MOVE.L        (A7)+,A1        ; restore event record pointer
  211.         ADDQ.L        #2,A7            ; pop pre-result; post-result in D0
  212.         ASL.W        #8,D0            ; bump C boolean to Lisa
  213.         MOVE.W        D0,8(A7)        ; stash result where caller expects it
  214.         MOVE.B        #false,inJGNE    ; mark myJGNE not busy
  215. @1        MOVE.L        gOldJGNE,A0        ; get previous jGNE
  216.         MOVE.L        (A7)+,A4        ; restore A4
  217.         MOVE.L        A0,-(A7)        ; return to previous jGNE
  218.     }
  219. }
  220.  
  221.  
  222. //****************************************************************
  223. void xDoAnimation(void);
  224. void xDoAnimation()
  225. {
  226.     GrafPtr        savP;
  227.     CGrafPort    dPort;
  228.  
  229.     // Create a new GrafPort on top of the current port so as to 
  230.     // disturb the graphics world as little as possible. This
  231.     // new GrafPort is the default through our copying operations.
  232.     
  233.     GetPort( &savP);
  234.     OpenCPort( (CGrafPtr)&dPort);
  235.     SetPort( (GrafPtr)&dPort);
  236.  
  237.     // Do something fun
  238.     ;
  239.  
  240.     SetPort( savP);
  241.     ClosePort( (GrafPtr)&dPort);
  242.  
  243.     return;
  244. }
  245.  
  246. //****************************************************************
  247. #define MAX_INC    18
  248.  
  249. void DoAnimation( Rect trshR)
  250. {
  251.     GrafPtr        savP;
  252.     CGrafPort    dPort;
  253.     Rect        savScrnR, picR, offBufR, wR;
  254.     Rect        tmpR, tmpR_0;
  255.     GWorldPtr    savScrnGWPtr, picGWPtr, offBufGWPtr;
  256.     PixMapHandle    pm;
  257.     GWorldPtr     savGW;
  258.     GDHandle      savGdH;
  259.     OSErr        err;
  260.     short        cnt, vInc, del, curAccl;
  261.     long        t, startT;
  262.     THz         savZone;
  263. #ifdef APP
  264.     Handle        pH;
  265. #endif
  266.     
  267.             //Debugger();
  268. /*
  269.     if (gSound != NULL && gSndChP != NULL) {
  270.         SndPlay( gSndChP, gSound, true);
  271.     }
  272. */
  273.     savZone = GetZone();
  274.     SetZone( SystemZone());
  275.  
  276.     // Save the 'Real' orignial port...
  277.     GetPort( &savP);
  278.  
  279.     // Create a new GrafPort on top of the current port so as to 
  280.     // disturb the graphics world as little as possible. This
  281.     // new GrafPort is the default through our copying operations.
  282.     
  283.     OpenCPort( (CGrafPtr)&dPort);
  284.     SetPort( (GrafPtr)&dPort);
  285.     
  286.     GetGWorld( &savGW, &savGdH);
  287.  
  288. #ifdef APP
  289.     //GetScriptableFinderTrashPos( false, kAEWaitReply, false, &trshR);
  290.     trshR.left = 400;
  291.     trshR.right = trshR.left + 32;
  292.     trshR.top = 640;
  293.     trshR.bottom = trshR.top + 32;
  294. #endif
  295.  
  296.     
  297.     // Get the picture
  298. #ifdef APP
  299.     pH = GetResource( 'PICT', 200);    if ( pH == 0) goto DONE;
  300.     picR = (**(PicHandle)pH).picFrame;
  301. #else
  302.     picR = (**(PicHandle)gP->pH).picFrame;
  303. #endif
  304.     
  305.     // calc drawing sizes
  306.     //  TO DO: work on non-main screen correctly...
  307.     
  308.     // savScr, tall column of saved screen
  309.     savScrnR.top = 0;
  310.     savScrnR.left = trshR.left;
  311.     savScrnR.right = savScrnR.left + (picR.right-picR.left);
  312.     savScrnR.bottom = trshR.bottom;
  313.     
  314.     offBufR = picR;
  315.     offBufR.bottom += MAX_INC;
  316.     wR = savScrnR;
  317.     wR.top += 24;
  318.     wR.bottom = wR.top + picR.bottom - picR.top + MAX_INC;
  319.     
  320.     ASSERT(savScrnR.left < savScrnR.right);
  321.     ASSERT(savScrnR.top < savScrnR.bottom);
  322.     // create offscreen worlds
  323.     err = NewGWorld( &savScrnGWPtr,0,&savScrnR,0,0,useTempMem);    if ( err != noErr) goto DONE;
  324.     err = NewGWorld( &picGWPtr,0,&picR,0,0,useTempMem);    if ( err != noErr) goto DONE;
  325.     err = NewGWorld( &offBufGWPtr,0,&offBufR,0,0,useTempMem);    if ( err != noErr) goto DONE;
  326.     
  327.     // init drawing
  328.     SetGWorld( picGWPtr, 0);
  329.     EraseRect( &picGWPtr->portRect);
  330. #ifdef APP
  331.     DrawPicture( (PicHandle)pH, &picR);
  332. #else
  333.     DrawPicture( (PicHandle)gP->pH, &picR);
  334. #endif
  335.  
  336.     SetGWorld( offBufGWPtr, 0);
  337.     LockPixels(GetGWorldPixMap(offBufGWPtr));
  338.     EraseRect( &offBufGWPtr->portRect);
  339.  
  340.         // the savScrn rect is always 0,0 -> top,left
  341.     tmpR = savScrnR;
  342.     tmpR.right -= tmpR.left;
  343.     tmpR.left -= tmpR.left;
  344.     tmpR.bottom -= tmpR.top;
  345.     tmpR.top -= tmpR.top;
  346.     SetGWorld( savScrnGWPtr, 0);
  347.     EraseRect( &savScrnGWPtr->portRect);
  348.     LockPixels((pm=GetGWorldPixMap(savScrnGWPtr)));
  349.     CopyBits(    (BitMap*)(&(((GrafPtr)&dPort)->portBits)),
  350.                 (BitMap*)(*pm),
  351.                 &savScrnR, &tmpR,
  352.                 patCopy, 0);
  353.  
  354. #define BASE_INC    1
  355.     // Animation Loop 
  356.     startT = TickCount();
  357.     for ( curAccl=1, del=1, cnt=0; cnt<savScrnGWPtr->portRect.bottom/6; cnt++) {
  358.         if ( cnt%5 == 0) curAccl++;
  359.         vInc = BASE_INC + curAccl;
  360.         wR.bottom += vInc;
  361.         wR.top += vInc;
  362.         
  363.         // copy sav to off
  364.         SetGWorld( offBufGWPtr, 0);
  365.         tmpR = wR;
  366.         tmpR.right -= tmpR.left;
  367.         tmpR.left -= tmpR.left;
  368.         tmpR.bottom -= tmpR.top;
  369.         tmpR.top -= tmpR.top;
  370.         tmpR_0 = wR;
  371.         tmpR_0.right -= tmpR_0.left;
  372.         tmpR_0.left -= tmpR_0.left;
  373.         LockPixels((pm=GetGWorldPixMap(offBufGWPtr)));
  374.         CopyBits(    (BitMap*)(*(savScrnGWPtr->portPixMap)), 
  375.                     (BitMap*)(*pm),
  376.                     &tmpR_0, &tmpR,
  377.                     patCopy, 0);
  378.  
  379.         // copy pic to off, picR is already 0-based
  380.         tmpR = picR;
  381.         tmpR.top += MAX_INC;
  382.         tmpR.bottom += MAX_INC;
  383.         CopyBits(    (BitMap*)(*(picGWPtr->portPixMap)), 
  384.                     (BitMap*)(*pm),
  385.                     &picR, &tmpR,
  386.                     patOr, 0);
  387.  
  388.         // copy off to dPort
  389.         tmpR = wR;
  390.         tmpR.right -= tmpR.left;
  391.         tmpR.left -= tmpR.left;
  392.         tmpR.bottom -= tmpR.top;
  393.         tmpR.top -= tmpR.top;
  394.         SetGWorld( savGW, savGdH);
  395.         CopyBits(    (BitMap*)(*(offBufGWPtr->portPixMap)), 
  396.                     (BitMap*)(&(((GrafPtr)&dPort)->portBits)),
  397.                     &tmpR, &wR,
  398.                     patCopy, 0);
  399.  
  400.         if ( t != startT) {
  401.             Delay( del, &t);
  402.         }
  403.     }
  404.     
  405.     // Clean up
  406.     DisposeGWorld( savScrnGWPtr);
  407.     DisposeGWorld( picGWPtr);
  408.     DisposeGWorld( offBufGWPtr);
  409.  
  410. DONE:
  411.  
  412.     SetPort( savP);
  413.     ClosePort( (GrafPtr)&dPort);
  414.  
  415.     SetZone( savZone);
  416.  
  417.     return;
  418. }
  419.  
  420.  
  421. //***********************************************************************************
  422. //                                                        E N D   O F   L I S T I N G
  423.  
  424.